#encoding=utf8
'''
Created on Sep 18, 2014

@author: jingyang <jingyang@smalltreemedia.com>
'''
from django.core.mail.message import EmailMultiAlternatives

import settings
from threads import EmailThread
import uuid
import os
from django.core.serializers.json import DjangoJSONEncoder
import json
from django.http.response import HttpResponse
import calendar
import datetime
import re
import cgi
import urllib
from oauth2client.client import SignedJwtAssertionCredentials
import gspread
import urllib2
import time
from django.contrib.admin.filters import SimpleListFilter
from django.utils import timezone


def field(header, **kwargs):
    def make_field(fun):
        for k, v in kwargs.iteritems():
            setattr(fun, k, v)
        fun.short_description = header
        return fun
    return make_field


def email_sending(subject='', html='', to=[]):
    if settings.DEBUG or settings.STAGING:
        return
    EmailThread(subject, settings.EMAIL_HOST_USER, html, to).start()


#def email_sending(subject='', msg='', html='', to=[]):
#    content = EmailMultiAlternatives(subject, msg, settings.EMAIL_HOST_USER, to)
#    content.attach_alternative(html, "text/html")
#    if not settings.DEBUG:
#        content.send(fail_silently=False)

def get_uuid():
    """
    get a random UUID
    """
    return str(uuid.uuid4())


def rename_file(file, file_name=None):
    """
    rename uploaded file with uuid or given file name
    return: renamed file object
    """
    ext = os.path.splitext(file.name)[1]
    file.name = "%s%s" % (file_name or get_uuid(), ext)
    return file


class JsonResponse(HttpResponse):
    """
    An HTTP response class that consumes data to be serialized to JSON.

    :param data: Data to be dumped into json. By default only ``dict`` objects
      are allowed to be passed due to a security flaw before EcmaScript 5. See
      the ``safe`` parameter for more information.
    :param encoder: Should be an json encoder class. Defaults to
      ``django.core.serializers.json.DjangoJSONEncoder``.
    :param safe: Controls if only ``dict`` objects may be serialized. Defaults
      to ``True``.
    """

    def __init__(self, data, encoder=DjangoJSONEncoder, safe=True, **kwargs):
        if safe and not isinstance(data, dict):
            raise TypeError('In order to allow non-dict objects to be '
                'serialized set the safe parameter to False')
        kwargs.setdefault('content_type', 'application/json')
        data = json.dumps(data, cls=encoder)
        super(JsonResponse, self).__init__(content=data, **kwargs)


def add_months(sourcedate, months=1):
    '''
    get the date after 'months' from 'sourcedate'
    '''
    month = sourcedate.month - 1 + months
    year = sourcedate.year + month / 12
    month = month % 12 + 1
    day = min(sourcedate.day, calendar.monthrange(year, month)[1])
    return datetime.date(year, month, day)


re_string = re.compile(r'(?P<htmlchars>[<&>])|(?P<space>^[ \t]+)|(?P<lineend>\r\n|\r|\n)|(?P<protocal>(^|\s)((http|ftp|https)://.*?))(\s|$)', re.S|re.M|re.I)


def plaintext2html(text, tabstop=4):
    def do_sub(m):
        c = m.groupdict()
        if c['htmlchars']:
            return cgi.escape(c['htmlchars'])
        if c['lineend']:
            return '<br>'
        elif c['space']:
            t = m.group().replace('\t', '&nbsp;' * tabstop)
            t = t.replace(' ', '&nbsp;')
            return t
        elif c['space'] == '\t':
            return ' ' * tabstop
        else:
            url = m.group('protocal')
            if url.startswith(' '):
                prefix = ' '
                url = url[1:]
            else:
                prefix = ''
            last = m.groups()[-1]
            if last in ['\n', '\r', '\r\n']:
                last = '<br>'
            return "%s<a target='_blank' href='%s'>%s</a>%s" % (prefix, url, url, last)
    return re.sub(re_string, do_sub, text)


def api_call(url, param={}, method='GET', headers={}):
    '''
    get data from other system via api
    '''
    if isinstance(param, dict):
        param = urllib.urlencode(param)
    try:
        if method == 'GET':
            req = urllib2.Request('%s?%s' % (url, param), headers=headers)
        else:
            req = urllib2.Request(url, param, headers)
        r = urllib2.urlopen(req).read()
        return json.loads(r)
    except Exception, e:
        return {'msg': e, 'code': -1}


def gspread_oauth2_login():
    '''
    gspread.login(email, password) does not work any more
    changed to oauth2
    '''
    json_key = json.load(open('pts_gspread.json'))
    scope = ['https://spreadsheets.google.com/feeds']
    credentials = SignedJwtAssertionCredentials(json_key['client_email'],
        json_key['private_key'], scope)
    gc = gspread.authorize(credentials)
    return gc


def str_is_date(input_string, date_format='%Y-%m-%d'):
    try:
        time.strptime(input_string, date_format)
        return True
    except ValueError:
        return False


class DateListFilter(SimpleListFilter):

    title = None
    parameter_name = None
    filter_field = None

    def lookups(self, request, model_admin):
        if self.parameter_name == 'year':
            date_range = range(2014, timezone.now().year + 1)
        elif self.parameter_name == 'month':
            date_range = range(1, 13)
        elif self.parameter_name == 'day':
            date_range = range(1, 32)
        return tuple([(x, x) for x in date_range])

    def queryset(self, request, queryset):
        if self.value():
            return queryset.filter(\
                **{'%s__%s' % (self.filter_field, self.parameter_name): self.value()})
        return queryset


def this_monday(d):
    return d - datetime.timedelta(days=d.weekday())


def this_sunday(d):
    return this_monday(d) + datetime.timedelta(days=6)


def this_week(d):
    return this_monday(d), this_sunday(d)
